package com.apestech.framework.db.session;

import com.apestech.framework.db.Format;
import com.apestech.framework.db.SqlResultSet;
import com.apestech.framework.db.SqlTemplate;
import com.apestech.framework.db.callback.QueryCallBackHandler;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.SqlParam;
import com.apestech.framework.sql.condition.ConditionMap;
import java.util.ArrayList;

/**
 * @author hup
 * @create 2019-02-13-14:25
 */
public class ResultQuery extends SessionUtil{
    private SqlParam sqlparam;
    private SqlTemplate cn;

    public ResultQuery(SqlTemplate cn, SqlParam sqlparam) throws Exception {
        this.cn=cn;
        this.sqlparam=sqlparam;
        try {
            this.sqlparam.setTimestampField(this.sqlparam.getSession().getSpecialField().getTimestamp());
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public int count(String sql, JSONArray param) throws Exception {
        final int[] i = new int[1];
        this.cn.query(sql, param,  new QueryCallBackHandler(){
            @Override
            public void getData(SqlResultSet rs, JSONArray rslist) throws Exception {
                while(rs.next()){
                    i[0] =rs.getInt(1);
                }
            }
        }, null, null);
        return i[0];
    }

    private JSONObject sum(String sql, JSONArray param, ConditionMap conParam) throws Exception {
        final JSONObject[] out = new JSONObject[1];
        out[0]=new JSONObject();
        this.cn.query(sql, param,  new QueryCallBackHandler(){
            @Override
            public void getData(SqlResultSet rs, JSONArray rslist) throws Exception {
                if(rs.next()){
                    out[0]=rs.toRowJson();
                    /*int len=rs.getColumnCount();
                    for(int i=0; i<len; i++){
                        String key=rs.getColumns()[i];
                        out[0].put(key, rs.getObject(key));
                    }*/
                }
            }
        }, conParam, conParam.getTimeField());
        return out[0];
    }

    private void queryForResultSet(String sql, QueryCallBackHandler queryCallBackHandler, ConditionMap conParam) throws Exception{
        if(conParam==null || conParam.isPrintSql()){
            System.out.println(sql+";");
        }
        this.cn.query(sql, null, queryCallBackHandler,  conParam, conParam.getTimeField());
    }

    public void queryForResultSet(QueryCallBackHandler queryCallBackHandler) throws Exception {
        ConditionMap param=sqlparam.getParam();
        if(param!=null){
            boolean flag=false;
            if("query".equals(param.getPageType())){
                flag=needCount();
                if(flag){
                    getSum();
                    JSONObject m=sqlparam.getParam().getAllsum();
                    if(m!=null){
                        sqlparam.getParam().setTotal(m.getInteger("SYS_TOTAL"));
                    } else {
                        getCount();
                    }
                }
            }
            if(flag && param.getTotal()==0){
                try {
                    if(sqlparam.isPrintSql()){
                        System.out.println(sqlparam.getPrintSql()+";");
                    }
                    SqlResultSet rs=new SqlResultSet();
                    rs.setConParam(sqlparam.getParam());
                    queryCallBackHandler.getData(rs, null);
                    return;
                } catch (Exception e) {
                    throw new Exception(e);
                }
            } else {
                if((sqlparam.getParams()!=null && sqlparam.getParams().size()>0) ){
                    if(sqlparam.isPrintSql()){
                        System.out.println(sqlparam.getPrintSql()+";");
                    }
                    this.cn.query(sqlparam.getExecSql(), sqlparam.getParams(), queryCallBackHandler, sqlparam.getParam(), sqlparam.getTimestampField());
                } else {
                    queryForResultSet(sqlparam.getExecSql(), queryCallBackHandler, sqlparam.getParam());
                }
            }
        }
    }

    public void getSum() throws Exception {
        if(sqlparam.getParam().isXls()) return;
        if(sqlparam.getParam().isNoSum() && sqlparam.getParam().getPage()!=1) return;
        JSONObject m=null;
        if(sqlparam.getSumSql()!=null){
            m=sum(sqlparam.getSumSql(), sqlparam.getOParam(), sqlparam.getParam());
            sqlparam.getParam().setAllsum(m);
        }
        if(!sqlparam.getParam().isNoSum()){
            if(sqlparam.getPageSql()!=null && sqlparam.getPageSql().getSumSql()!=null){
                if(sqlparam.getParam().getTotal()>sqlparam.getParam().getSize())
                    m=sum(sqlparam.getPageSql().getSumSql(), sqlparam.getPageSql().getResParam(), sqlparam.getParam());
                sqlparam.getParam().setSum(m);
            }
        }
    }

    private boolean isPage(){
        if(sqlparam.getParam().getSize()<=0) return false;
        if(sqlparam.getParam().getRule()!=null){
            if(sqlparam.isPrintSql()){
                System.out.println(sqlparam.getParam().getRule().getPage()+";");
            }
            if(!"all".equals(sqlparam.getParam().getRule().getPage())){
                return true;
            }
        }
        return false;
    }

    private boolean needCount(){
        boolean flag=isPage();
        if(!flag){
            if(sqlparam.getParam().isXls()) flag=true;
        }
        return flag;
    }

    private void getCount() throws Exception {
        if(sqlparam.getParam().getTotal()==0){
            int i=count(sqlparam.getCountSql(), sqlparam.getOParam());
            sqlparam.getParam().setTotal(i);
        } else {
            try {
                sqlparam.getParam().setTotal(castToInt(sqlparam.getParam().getTotal()));
            } catch (Exception e) {
                throw new Exception(e);
            }
        }
    }

    private void setCountSum(SqlResultSet rs, boolean curPage) throws Exception {
        ConditionMap param=rs.getConParam();
        param.setTotal(param.getTotalPage()+1);
        if(curPage){
            param.getSum();
        }
        param.getAllsum();
        Format format=param.getFormat();
        if(format!=null){
            ArrayList<String> klist=format.getKeylist();
            int len=klist.size();
            for(int i=0;i<len;i++){

            }
        }

    }


}
